<?php

namespace Town\View;

use Town\View\TbParser as Parser;

/**
 * Tb模板对象
 */
class Tb
{
    /**
     * 配置:
     * template_root_dir 模板根目录
     * template_name     模板文件名称
     * 
     * @var null
     */
    private $conf   = null;
    
    // 解析器
    private $parser = null;

    // 参数
    private $map = [];


    /**
     * 基本配置
     * @param array $conf [description]
     */
    public function __construct($conf = [], $debug = false)
    {
        if (array_key_exists('template_name', $conf))
            $conf['template_name'] = $this->directory_path($conf['template_name']);

        $this->conf   = $conf;
        $this->debug  = $debug;
    }


    /**
     * 获取编译后的页面
     * @return [type] [description]
     */
    public function render()
    {
        $path = $this->compile();
        ob_start();
        include($path);
        $text = ob_get_contents();
        ob_end_clean();
        return $text;
    }


    /**
     * 使用 $name,$parameters 直接获取渲染结果
     * @param  string $name       模板名称
     * @param  array  $parameters 参数列表
     * @return text
     */
    public function fetch($name, $parameters = array())
    {
        $this->conf['template_name'] = $this->directory_path($name);
        $this->map = $parameters;
        return $this->render();
    }



    /**
     * 编译脚本
     * @return [type] [description]
     */
    public function compile()
    {
        $this->parser = new Parser($this->conf);
        $path = $this->full_ori_path($this->conf['template_name']);
        $md5  = md5_file($path);

        $ds   = DIRECTORY_SEPARATOR;
        $path = $this->conf['cache_root_dir']."{$ds}{$md5}";
        if ($this->debug || !is_readable($path)) {
            $content = $this->parser->exec();
            file_put_contents($path, $content);
        }

        return $path;
    }


    /**
     * 参数绑定
     * @param  [type] $key     [description]
     * @param  [type] $default [description]
     * @return [type]          [description]
     */
    public function args($key, $default = null)
    {
        $key = ltrim($key, '$');

        // $base->name
        if (strpos($key, '->') !== false) {
            list($obj, $key) = explode('->', $key);
            return ($this->map[$obj])->{$key};
        }

        // $val['name']; 
        if (strpos($key, '[') !== false) {
            list($obj, $key) = explode('[', $key);
            $key = ltrim($key, ']');
            return ($this->map[$obj])[$key];
        }

        // TODO::处理匿名
        return $this->map[$key];
    }


    /**
     * 设置数据
     * @param mixed $name 参数名称
     * @param mixed $val  值
     */
    public function setParameter($name, $val)
    {
        $this->map[$name] = $val;
    }


    /**
     * 处理路径
     * @param  [type] $path [description]
     * @return [type]       [description]
     */
    private function directory_path($path)
    {
        $ds   = DIRECTORY_SEPARATOR;
        $path = str_replace('.', $ds, rtrim($path, $ds));

        return $path;
    }


    /**
     * 获取源文件 path
     * @param  [type] $name [description]
     * @return [type]       [description]
     */
    private function full_ori_path($name)
    {
        $ds   = DIRECTORY_SEPARATOR;
        $path = rtrim($this->conf['template_root_dir'], $ds).$ds.$name;
        $ext  = $this->conf['template_ext'] ?? $this->parser->template_ext;
        $path = "{$path}.{$ext}";
        return$path;
    }
}